try { var dummy = XMLTokenAuth; } catch ( e ) {

/**
 * XMLTokenAuth - like other Authentication components listens for onConnect
 * events and authenticates the client. If the client cannot be
 * authenticated the component passes the client to rtcf.authenticationFault(client, fault)
 * along with a message or fault object about the rejection.
 * If the client is authenticated the Authenticaton component calls
 * rtcf.authenticationResult(client, user). 
 * (Also, see the User class.)
 *
 * XMLTokenAuth attempts to validate the client by making sending a token in a query string  
 * to a ColdFusion or other application that can look up the token and send back xml information. 
 * It makes use of XML class and XML.sendAndLoad method.
 * The client is held by the framework in a pending state until XMLTokenAuth 
 * calls either authenticationResult or authenticationFault
 */
function XMLTokenAuth(){
	// Do nothing. Use the init method instead which is called by rtcf.
}

// Required for AS 1 inheritance.
XMLTokenAuth.prototype = new RTCFComponent();

/**
 * Setup the onConnect listener - which is the only event this component needs.
 * Create the xmlSender object and a free pool of xml receiver objects.
 */
XMLTokenAuth.prototype.init = function(){
	trace("XMLTokenAuth.init>");
	
	this.queryURI = "http://127.0.0.1/virtualStudio/mediaServerComponents/validateStudioToken.cfm?token=";

	// init component properties and its resources here...
	this.rtcf.addListener("onConnect", this);
	
	// Create the XMLSender class. 
	// The XMLReciever objects will be kept in a free pool to limit memory usage
	// as clients connect/disconnect. Need a getXMLReceiver method.
	// Need to keep track of pending clients? Or just get them from rtcf's pending clients object?
	var owner = this;
	this.xmlSender = new XML();
	this.xmlSender.contentType = "text/xml";
	
	// Array of receiver objects that can be reused:
	this._receiverPool = []; 
}

/**
 * Gets an XMLReceiver object from the free pool or generates a new one if none are left.
 * The XMLReceiver object will is used to keep track of the client trying to authenticate
 * (see xmlReceiver.client) and to handle the result that is returned from the server.
 * If things go wrong the onHTTPStatus will be passed a status other than 200
 * and onLoad will be passed false. Inside the onLoad and onHTTPStatus methods
 * "this" refers to the xmlReceiver so we use the owner variable to refer to this
 * XMLTokenAuth component.
 */
XMLTokenAuth.prototype.getXMLReceiver = function(){
	// trace("XMLTokenAuth.getXMLReceiver>");
	if(this._receiverPool.length > 0){
		return(this._receiverPool.pop());
	}
	else {
		var owner = this;
		var xmlTokenReceiver = new XML();
		xmlTokenReceiver.ignoreWhite = true;
		xmlTokenReceiver.onLoad = function(success){
			//trace("xmlTokenReceiver,onLoad> success: " + success);
			if(! success) return;
			var tokenInfo = {};
			// The tag we get back will be either <userInfo> or <error>
			var nodeName = this.firstChild.nodeName;
			if(nodeName == "error"){
				owner.getTokenInformationFault(this, "Token Record not found.");
			}	
			else if (nodeName == "userInfo"){
				var attributes = this.firstChild.attributes;
				for (var p in attributes) {
					tokenInfo[p] = attributes[p];
				}			
				owner.getTokenInformationResult(this, tokenInfo);
			}
			else {
			owner.getTokenInformationFault(this, "Unrecognized return tag from Web application: " + nodeName);
			}
		}
		xmlTokenReceiver.onHTTPStatus = function(status){
			//trace("xmlTokenReceiver,onLoad> status: " + status);
			if (status != 200) owner.getTokenInformationFault(this, "HTTP Status: " + status);
		}
		
		return(xmlTokenReceiver);
	}

}

/**
 * Rather than dispose of an xmlTokenReceiver object keep it on the free pool of
 * receiver objects for use by another client.
 */
XMLTokenAuth.prototype.saveXMLReceiver = function(xmlTokenReceiver){
	// trace("XMLTokenAuth.saveXMLReceiver> xmlTokenReceiver: " + xmlTokenReceiver);
	// should check the type here and not push junk on the stack.
	if (xmlTokenReceiver.client) xmlTokenReceiver.client = null;
	xmlTokenReceiver.parseXML("<empty/>")
	this._receiverPool.push(xmlTokenReceiver);
}

/**
 * getTokenInformationResult is passed a reference to the xmlReceiver and the info
 * the server sent back when authenticating the token. If we got this far
 * the client is authenticated. The xmlReceiver must be passed in so it can
 * be placed on the free pool.
 */
XMLTokenAuth.prototype.getTokenInformationResult = function(xmlReceiver, info){
	//trace("XMLTokenAuth.getTokenInformationResult> xmlReceiver, info: " + xmlReceiver + ", " + info);
	
	var client = xmlReceiver.client;
	this.saveXMLReceiver(xmlReceiver);
	
	var user = new User(client.id, info.user_name);
	var roleNameArray = info.roles.split(",");
	for(var i = 0; i < roleNameArray.length; i++){
		var roleName = roleNameArray[i];
		user.roles[roleName] = true;
	}
	// Copy everything but the ip address into the user properties:
	user.properties = {};
	for (var p in info){
		if (p == "ip_address") continue;
		user.properties[p] = info[p];
	}
	user.type = "AuthenticatedUser";
	this.rtcf.authenticationResult(client, user);	
}

XMLTokenAuth.prototype.getTokenInformationFault = function(xmlReceiver, status){
	// trace("XMLTokenAuth.getTokenInformationFault> xmlReceiver, status: " + xmlReceiver + ", " + status);

	var client = xmlReceiver.client;
	this.saveXMLReceiver(xmlReceiver);
	this.rtcf.authenticationFault(client, "Invalid Credentials.");
}

/** 
 * 
 */
XMLTokenAuth.prototype.onConnect = function(client, credentials){
	// trace("XMLTokenAuth.onConnect> client, credentials: " + client + ", " + credentials );
	if (!credentials || typeof credentials.token != "string"){
		this.rtcf.authenticationFault(client, "Invalid data. A credentials.token must be passed to the server for authentication to take place.");
		trace("ERROR: Invalid credentials in XMLTokenAuth.onConnect");
		return;
	}
	
	var xmlReceiver = this.getXMLReceiver();
	xmlReceiver.client = client;
	
	this.xmlSender.sendAndLoad(this.queryURI + credentials.token, xmlReceiver);

}


} // end catch
